#include "Command.h"
#include "Tools.h"
#include "Redis.h"

#include <bitset>

extern shared_ptr<Redis> redis;



string SetCommand::excute_command() {
    
    for(int i=0;i<args.size();i+=2){
        if(i+3 < args.size() && (args[i+2]=="PX"|| args[i+2]=="px")){
            redis->mp[args[i]]=make_pair(args[i+1],chrono::system_clock::now()+chrono::milliseconds(stoi(args[i+3])));
            i+=2;
        }else{
            redis->mp[args[i]]=make_pair(args[i+1],chrono::time_point<chrono::system_clock>());
        }
    }
    return simple_string("OK");
    
}

string GetCommand::excute_command() {
    string back_msg;
    auto it=redis->mp.find(args[0]);
    if(it!=redis->mp.end()){
        if(it->second.second.time_since_epoch().count()==0){
            back_msg=bulk_string(it->second.first);
        }else{
        //auto now_time=chrono::system_clock::now();
            if(chrono::system_clock::now() < it->second.second){
                back_msg=bulk_string(it->second.first);
            }else{
                redis->mp.erase(it);
                back_msg=nil_bulk_string();
            }
        }
    }else{
        back_msg=nil_bulk_string();
    }
    return back_msg;
}


string InfoCommand::excute_command(){
    string back_msg;
    if(redis->redis_type==RedisType::REDIS_MASTER){
        RedisMaster* master=dynamic_cast<RedisMaster*>(redis.get());
        back_msg="role:master\n";
        back_msg+="master_replid:"+master->master_replid+"\n";
        back_msg+="master_repl_offset:"+to_string(master->master_repl_offset)+"\n";
    }else if(redis->redis_type==RedisType::REDIS_SLAVE){
        back_msg="role:slave\n";
    }

    return bulk_string(back_msg);
    
}

string PsyncCommand::excute_command(){
    assert(redis->redis_type==RedisType::REDIS_MASTER);
    
    RedisMaster* master=dynamic_cast<RedisMaster*>(redis.get());
    vector<string> vct{"FULLRESYNC",master->master_replid,to_string(0)};
    //空的rdb文件 实现
    string hex_number="524544495330303131fa0972656469732d76657205372e322e30fa0a72656469732d62697473c040fa056374696d65c26d08bc65fa08757365642d6d656dc2b0c41000fa08616f662d62617365c000fff06e3bfec0ff5aa2";
    string bin_number=hex_to_bin(hex_number);
    return simple_string(vct) +"$"+to_string(bin_number.size())+"\r\n"+bin_number;
}